home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 2 / CU Amiga Magazine's Super CD-ROM 02 (1996)(EMAP Images)(GB)[!][issue 1996-04].iso / magazine / amiga_e / iconvert.lha / Iconvert.e
Text File  |  1993-06-14  |  9KB  |  284 lines

  1. /* Iconvert.e
  2.  
  3.    This little utility converts a '.i' assembly include file
  4.    into an E binary module.
  5.    it understands '=' and 'EQU' for constant definitions, and builds
  6.    OBJECTs out of STRUCTURE definitions (from "exec/types.i").
  7.    it needs a macroassembler like A68k to run.
  8.    USAGE: iconvert <.ifile>       */
  9.  
  10. /* Version  Author  Change(s)
  11.      v0.1s  Son Le  LABELs are no longer ignored, but instead are
  12.                     converted to empty arrays. Takes no space, but
  13.                     can still be referenced.
  14.                     Look for /* -- v0.1s additions -- */ in source.
  15. */
  16.  
  17. OBJECT def
  18.   type:INT,name
  19. ENDOBJECT
  20.  
  21. ENUM T_ARRAY,T_CHAR,T_INT,T_LONG=4,T_CONST=$10,T_STRUCT,T_END
  22. ENUM ER_NONE,ER_IN,ER_OUT,ER_MEM,ER_WORK,ER_BREAK,ER_FORM,ER_TEMPW,
  23.      ER_INVOKE,ER_TEMPR,ER_OFORM,ER_I
  24.  
  25. CONST MAX_DEF=2500,IDMAX=10
  26.  
  27. DEF defs[MAX_DEF]:ARRAY OF def,
  28.     infile[100]:STRING,outfile[100]:STRING,
  29.     handle=NIL,flen,buf,bbuf,defn=0,line=0,mode=0,a
  30.  
  31. PROC main()
  32.   WriteF('Iconvert v0.1s 1992 $#%!\n\n')
  33.   readinfile()
  34.   collectidents()
  35.   makeasmfile()
  36.   invokea68k()
  37.   readbinary()
  38.   makemodule()
  39.   error(ER_NONE)
  40. ENDPROC
  41.  
  42. PROC readinfile()
  43.   DEF len
  44.   StrCopy(infile,arg,ALL)
  45.   len:=EstrLen(infile)-2
  46.   IF infile[len]<>"." THEN error(ER_I)
  47.   StrCopy(outfile,arg,ALL); outfile[len+1]:="m"
  48.   IF (flen:=FileLength(infile))<1 THEN error(ER_IN)
  49.   IF (buf:=New(flen+1))=NIL THEN error(ER_MEM)
  50.   buf[flen]:=10
  51.   IF (handle:=Open(infile,OLDFILE))=NIL THEN error(ER_IN)
  52.   IF Read(handle,buf,flen)<>flen THEN error(ER_IN)
  53.   Close(handle); handle:=NIL
  54. ENDPROC
  55.  
  56. PROC collectidents()
  57.   DEF p,a,id[IDMAX]:ARRAY OF LONG,num,f,c,end,zero=NIL,macro=FALSE
  58.   DEF struct=FALSE,d:PTR TO def,size,work[10]:STRING
  59.   WriteF('Now trying to convert "\s".\n',infile)
  60.   INC line; p:=buf; end:=p+flen; d:=defs
  61.   WHILE p<end
  62.     FOR a:=0 TO IDMAX-1 DO id[a]:=0
  63.     num:=0; f:=TRUE
  64.     WHILE f
  65.       c:=p[]++
  66.       IF zero; zero[]:=0; zero:=NIL; ENDIF
  67.       IF (c=10) OR (c=0)
  68.         f:=FALSE
  69.       ELSEIF (c<=" ") OR (c=",")
  70.       ELSEIF (c=";") OR (c="*")
  71.         f:=FALSE
  72.         WHILE p[]++<>10 DO NOP
  73.       ELSE
  74.         id[num]:=p-1
  75.         WHILE ((c:=p[]++)>" ") AND (c<>",") AND (c<>";") DO NOP
  76.         p--; zero:=p
  77.         IF num++=IDMAX THEN error(ER_WORK)
  78.       ENDIF
  79.     ENDWHILE
  80.     IF num
  81.       size:=-1
  82.       IF StrCmp(id[1],'MACRO',ALL)
  83.         macro:=TRUE
  84.       ELSEIF StrCmp(id[1],'EQU',ALL) OR StrCmp(id[1],'=',ALL) OR StrCmp(id[1],'equ',ALL)
  85.         IF macro=FALSE
  86.           d.type:=T_CONST
  87.           d.name++:=id[0]
  88.           defn++
  89.         ENDIF
  90.       ELSEIF StrCmp(id[0],'STRUCTURE',ALL)
  91.         struct:=TRUE
  92.         d.type:=T_STRUCT
  93.         d.name++:=id[1]
  94.         defn++
  95.         IF (InStr(id[2],'SIZEOF',0)<>-1) OR (InStr(id[2],'SIZE',0)<>-1)
  96.           IF defn>=MAX_DEF THEN error(ER_WORK)
  97.           d.type:=T_ARRAY
  98.           c:=InStr(id[2],'_',0)
  99.           IF c<>-1 THEN PutChar(id[2]+c,0)
  100.           d.name++:=id[2]
  101.           defn++
  102.     ELSEIF (Val(id[2],{c})<>0) OR (c=0)
  103.           WriteF('WARNING: object "\s" does not start at offset 0\n',id[1])
  104.         ENDIF
  105.       ELSEIF StrCmp(id[0],'LABEL',ALL)
  106.         IF struct=FALSE THEN error(ER_FORM)
  107.         IF (InStr(id[1],'SIZEOF',0)<>-1) OR (InStr(id[1],'SIZE',0)<>-1)
  108.           struct:=FALSE
  109.           d.type:=T_END
  110.           d.name++:=id[1]
  111.           defn++
  112.         ELSE                                     /* -- v0.1s additions -- */
  113.           IF defn>=MAX_DEF THEN error(ER_WORK)   /* now processes LABELs  */
  114.           d.type:=T_ARRAY                        /* to be empty arrays so */
  115.           d.name++:=id[1]                        /* structures can be ac- */
  116.           defn++                                 /* cessed by LABELs w/o  */
  117.         ENDIF                                    /* loss of compatibility */
  118.       ELSEIF StrCmp(id[0],'BYTE',ALL); size:=1
  119.       ELSEIF StrCmp(id[0],'UBYTE',ALL); size:=1
  120.       ELSEIF StrCmp(id[0],'WORD',ALL); size:=2
  121.       ELSEIF StrCmp(id[0],'UWORD',ALL); size:=2
  122.       ELSEIF StrCmp(id[0],'SHORT',ALL); size:=2
  123.       ELSEIF StrCmp(id[0],'USHORT',ALL); size:=2
  124.       ELSEIF StrCmp(id[0],'LONG',ALL); size:=4
  125.       ELSEIF StrCmp(id[0],'ULONG',ALL); size:=4
  126.       ELSEIF StrCmp(id[0],'APTR',ALL); size:=4
  127.       ELSEIF StrCmp(id[0],'BPTR',ALL); size:=4
  128.       ELSEIF StrCmp(id[0],'CPTR',ALL); size:=4
  129.       ELSEIF StrCmp(id[0],'BSTR',ALL); size:=4
  130.       ELSEIF StrCmp(id[0],'BOOL',ALL); size:=2
  131.       ELSEIF StrCmp(id[0],'FPTR',ALL); size:=4
  132.       ELSEIF StrCmp(id[0],'STRUCT',ALL); size:=0
  133.       ELSEIF StrCmp(id[1],'MACRO',ALL)
  134.         macro:=TRUE
  135.       ELSEIF StrCmp(id[0],'ENDM',ALL)
  136.         macro:=FALSE
  137.       ELSEIF StrCmp(id[0],'BITDEF',ALL)     /* depends on correctness */
  138.         c:=id[1]-1
  139.         FOR a:=1 TO id[2]-id[1]-1 DO c[]++:=c[1]
  140.         c[]++:="F"; c[]++:="_"
  141.         d.type:=T_CONST
  142.         d.name++:=id[1]-1
  143.         defn++
  144.       ELSEIF StrCmp(id[0],'EITEM',ALL)
  145.         d.type:=T_CONST
  146.         d.name++:=id[1]
  147.         defn++
  148.       ELSEIF StrCmp(id[0],'DEVCMD',ALL)
  149.         d.type:=T_CONST
  150.         d.name++:=id[1]
  151.         defn++
  152.       ELSEIF StrCmp(id[1],'SET',ALL) OR StrCmp(id[0],'IFND',ALL) OR StrCmp(id[0],'ENDC',ALL) OR StrCmp(id[0],'INCLUDE',ALL) OR StrCmp(id[0],'ENUM',ALL) OR StrCmp(id[0],'LIBENT',ALL) OR StrCmp(id[0],'LIBINIT',ALL) OR StrCmp(id[0],'LIBDEF',ALL) OR StrCmp(id[0],'DEVINIT',ALL) OR StrCmp(id[0],'FUNCDEF',ALL) OR StrCmp(id[0],'include',ALL) OR StrCmp(id[0],'IFD',ALL)
  153.       ELSE
  154.         IF macro=FALSE THEN error(ER_FORM)
  155.       ENDIF
  156.       IF size<>-1
  157.         IF (InStr(id[1],'Kludge',0)<>-1)       /* ask for deletion */
  158.           WriteF('Skip member "\s" (y/n)? >',id[1])
  159.           Read(stdout,work,2)
  160.           c:=work[0]
  161.         ELSE
  162.           c:=0
  163.         ENDIF
  164.         IF (c<>"y") AND (macro=FALSE)
  165.           IF struct=FALSE THEN error(ER_FORM)
  166.           IF size=1 THEN d.type:=T_CHAR ELSE IF size=2 THEN d.type:=T_INT ELSE IF size=4 THEN d.type:=T_LONG ELSE d.type:=T_ARRAY
  167.           d.name++:=id[1]
  168.           defn++
  169.         ENDIF
  170.       ENDIF
  171.       IF defn>=MAX_DEF THEN error(ER_WORK)
  172.     ENDIF
  173.     IF CtrlC() THEN error(ER_BREAK)
  174.     IF (line AND $F)=0 THEN WriteF('line=\d\b',line)
  175.     INC line
  176.   ENDWHILE
  177.   line:=0
  178. ENDPROC
  179.  
  180. PROC makeasmfile()
  181.   DEF a,oldout,d:PTR TO def
  182.   IF (handle:=Open('ram:iconvert.s',NEWFILE))=NIL THEN error(ER_TEMPW)
  183.   IF defn=0 THEN error(ER_FORM)
  184.   d:=defs
  185.   oldout:=SetStdOut(handle)
  186.   WriteF(' INCLUDE "\s"\n\n',infile)
  187.   FOR a:=1 TO defn
  188.     WriteF(' DC.L \s\n',d.name++)
  189.   ENDFOR
  190.   WriteF('\n END\n')
  191.   SetStdOut(oldout)
  192.   Close(handle); handle:=NIL
  193. ENDPROC
  194.  
  195. PROC invokea68k()
  196.   IF Execute('A68k -iINCLUDES: ram:iconvert.s',NIL,stdout)=FALSE THEN error(ER_INVOKE)
  197. ENDPROC
  198.  
  199. PROC readbinary()
  200.   DEF bsize
  201.   bsize:=defn*4+32
  202.   IF FileLength('ram:iconvert.o')<>bsize THEN error(ER_TEMPR)
  203.   bbuf:=New(bsize)
  204.   IF bbuf=NIL THEN error(ER_MEM)
  205.   IF (handle:=Open('ram:iconvert.o',OLDFILE))=NIL THEN error(ER_TEMPR)
  206.   IF Read(handle,bbuf,bsize)<>bsize THEN error(ER_TEMPR)
  207.   Close(handle); handle:=NIL
  208. ENDPROC
  209.  
  210. PROC makemodule()
  211.   DEF v:PTR TO LONG,work[3]:ARRAY OF INT,d:PTR TO def,l,x,obj=NIL
  212.   v:=bbuf+28; d:=defs
  213.   IF (handle:=Open(outfile,NEWFILE))=NIL THEN error(ER_OUT)
  214.   Write(handle,'EMOD',4)
  215.   FOR a:=1 TO defn
  216.     IF d.type=T_CONST
  217.       IF mode=2 THEN endobj(obj)
  218.       IF mode=0 THEN Write(handle,[1]:INT,2)
  219.       l:=StrLen(d.name)+1
  220.       work[0]:=IF Odd(l) THEN l+1 ELSE l
  221.       PutLong(work+2,v[]++)
  222.       Write(handle,work,6)
  223.       UpperStr(d.name)
  224.       Write(handle,d.name++,l)
  225.       IF Odd(l) THEN Write(handle,'',1)
  226.       mode:=1
  227.     ELSEIF d.type=T_END
  228.       IF mode<>2 THEN error(ER_OFORM)
  229.       mode:=0
  230.       Write(handle,[0,v[]++]:INT,4)
  231.       d++
  232.     ELSE
  233.       IF (mode=2) AND (d.type=T_STRUCT) THEN endobj(obj)
  234.       IF mode=1 THEN Write(handle,[0]:INT,2)
  235.       IF mode<>2
  236.         Write(handle,[2]:INT,2)
  237.         IF d.type<>T_STRUCT THEN error(ER_OFORM)
  238.         obj:=d.name
  239.       ENDIF
  240.       work[1]:=IF d.type=T_STRUCT THEN -1 ELSE d.type
  241.       work[2]:=v[]++
  242.       x:=InStr(d.name,'_',0)
  243.       IF x<>-1 THEN d.name:=d.name+x+1
  244.       LowerStr(d.name)
  245.       l:=StrLen(d.name)+1
  246.       work[0]:=IF Odd(l) THEN l+1 ELSE l
  247.       Write(handle,work,6)
  248.       Write(handle,d.name++,l)
  249.       IF Odd(l) THEN Write(handle,'',1)
  250.       mode:=2
  251.     ENDIF
  252.   ENDFOR
  253.   IF mode=2 THEN endobj(obj)
  254.   IF mode=1 THEN Write(handle,[0]:INT,2)
  255.   Close(handle); handle:=NIL
  256. ENDPROC
  257.  
  258. PROC endobj(obj)
  259.   Write(handle,[0,-1]:INT,4)
  260.   WriteF('WARNING: object "\s" has no SIZE\n',obj)
  261.   mode:=0
  262. ENDPROC
  263.  
  264. PROC error(er)
  265.   IF handle THEN Close(handle)
  266.   SELECT er
  267.     CASE ER_NONE;   WriteF('Done.\n')
  268.     CASE ER_IN;     WriteF('Could not read "\s"\n',infile)
  269.     CASE ER_OUT;    WriteF('Could not write "\s"\n',outfile)
  270.     CASE ER_MEM;    WriteF('Could not allocate memory\n')
  271.     CASE ER_WORK;   WriteF('Work buffer overflow\n')
  272.     CASE ER_BREAK;  WriteF('User terminated convertion\n')
  273.     CASE ER_FORM;   WriteF('.i file format error\n')
  274.     CASE ER_TEMPW;  WriteF('Trouble creating temporarily file\n')
  275.     CASE ER_TEMPR;  WriteF('Trouble reading temporarily file\n')
  276.     CASE ER_INVOKE; WriteF('Could not invoke A68k\n')
  277.     CASE ER_OFORM;  WriteF('Error in object order line \d in "ram:iconvert.s"\n',a+1)
  278.     CASE ER_I;      WriteF('Not a ".i" file: "\s"\n',infile)
  279.   ENDSELECT
  280.   IF line THEN WriteF('At line \d in file "\s"\n',line,infile)
  281.   IF er>0 THEN DeleteFile(outfile)
  282.   CleanUp(0)
  283. ENDPROC
  284.